package mammuthus.web.service

import java.text.SimpleDateFormat
import java.util
import java.util.Date
import javax.annotation.PostConstruct
import com.alibaba.fastjson.{JSONObject, JSON}
import com.webdm.common.tools.{NumberUtil, TimeUtil, CatchUtil}
import mammuthus.web.bean.{FileBean, AppInfoBean, SlaveBean}
import mammuthus.web.bean.{FileBean, AppInfoBean, SlaveBean}
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

import scala.beans.BeanProperty
import scala.collection.JavaConversions._

/**
 * Created by fengbingjian on 15/5/3 13:30.
 */
@Service
class SlaveService2 {

  val logger = LoggerFactory.getLogger(classOf[SlaveService])
  var master: String = null


  var masterUrl: String = null
  @Autowired
  @BeanProperty
  var settingService:SettingService = null


  @PostConstruct
  def init() = {
    val settings = settingService.getSettings
    master = settings.get("master.host")
    masterUrl = s"http://${master}:9003"
  }


  def getMaster: String = master

  def getSlave():util.List[SlaveBean] = {

    val src = CatchUtil.getSrc(s"${masterUrl}/slaves", false);
    return  JSON.parseArray(src, classOf[SlaveBean])
  }


  def install(app: String, version: String, slave: Array[String]) = {


    val dir = "/data/1/usr/local"

    val configUrl = s"${masterUrl}/app/config?appName=${app}&installPath=${dir}&slaves=${slave.mkString(",")}&appVersion=${version}"

    val installUrl = s"${masterUrl}/app/install?" +
      s"slaves=${slave.mkString(",")}&appVersion=${version}&" +
      s"url=${masterUrl}/${app}-${version}.tar.gz&" +
      s"filePath=${dir}/softwares/${app}-${version}.tar.gz&" +
      s"installPath=${dir}&" +
      s"appName=${app}&" +
      "tt=1800000"


    logger.info("install  {}", installUrl)

    val installResult = CatchUtil.getSrc(installUrl, false)
    logger.info("install {}", installResult)



    logger.info("install config {}", configUrl)
    val configResult = CatchUtil.getSrc(configUrl, false)
    logger.info("install config result {}", configResult)
  }


  def gitInstall(app: String, url: String, slave: Array[String]) = {


    val dir = "/data/1/usr/local"


    val installUrl = s"${masterUrl}/app/install?" +
      s"slaves=${slave.mkString(",")}&" +
      s"url=${url}&" +
      s"installPath=${dir}&" +
      s"appName=${app}&" +
      "tt=1800000"


    logger.info("install  {}", installUrl)

    val installResult = CatchUtil.getSrc(installUrl, false)
    logger.info("install {}", installResult)

  }

  def containerList(slaves:String,status:String) = {
    //?slaves=allwefantasy&status=up|exited|exception|all
    val url = s"${masterUrl}/app/list?slaves=$slaves&status=$status"
    val src = CatchUtil.getSrc(url, false)
    JSON.parseArray(src)
  }

  def appList():util.List[AppInfoBean] = {

    val url = s"${masterUrl}/app/list"
    val src = CatchUtil.getSrc(url, false)
    val json = JSON.parseArray(src).map(l => {

      val obj = l.asInstanceOf[JSONObject]
      obj.getObject("appInfo", classOf[AppInfoBean])
    })
    json

  }

  def appListSimple():util.List[String] = {

    val url = s"${masterUrl}/app/list"
    val src = CatchUtil.getSrc(url, false)
    val json = JSON.parseArray(src).map(l => {

      val obj = l.asInstanceOf[JSONObject]
      obj.getJSONObject("appInfo").getString("appName")
    })
    json

  }

  def appSlave(app: String):util.List[String] = {

    val url = s"${masterUrl}/app/list"
    val src = CatchUtil.getSrc(url, false)
    JSON.parseArray(src).filter(l => {

      val obj = l.asInstanceOf[JSONObject]

      obj.getJSONObject("appInfo").getString("appName") == app
    }).get(0).asInstanceOf[JSONObject].getJSONArray("hosts").map(l => l.toString)

  }


  def appControl(appName: String, slave: String,  shellCommand: String, appType: String, moduleFile: String):String = {

    var url = s"${masterUrl}/app/control?appName=${appName}&command=${shellCommand}&appType=${appType}&moduleFile=${moduleFile}"
    if(slave != null && "" != slave) url = url + "&slaves=" + slave
    logger.info("shell {}", url)
    val src = CatchUtil.getSrc(url, false)

    return JSON.parseArray(src).getJSONObject(0).getJSONObject("task").getString("taskId")
  }
  def getMethodShell(appName: String, slave: String, action: String, shellCommand: String, appType: String, moduleFile: String): String = {


    var taskId: String = null

    var url: String = null
    if("shell" == action){
      url = s"${masterUrl}/shell?slaves=${slave}&shellCommand=${shellCommand}"

    }else{

      url = s"${masterUrl}/app/control?appName=${appName}&command=${action}&appType=${appType}&moduleFile=${moduleFile}"
      if(slave != null && "" != slave) url = url + "&slaves=" + slave

    }

    logger.info("shell {}", url)
    val src = CatchUtil.getSrc(url, false)

    taskId = JSON.parseArray(src).getJSONObject(0).getJSONObject("task").getString("taskId")


    val taskUrl = s"${masterUrl}/shell/process?taskId=${taskId}&slaves=${slave}"

    logger.info("shell task {}",taskUrl)
    CatchUtil.getSrc(taskUrl, false)
  }

  def shell(appName: String, slave: String, action: String, shellCommand: String): String = {


    var taskId: String = null

    var url: String = null
    if("shell" == action){
      url = s"${masterUrl}/shell?slaves=${slave}&shellCommand=${shellCommand}"

    }else{

      url = s"${masterUrl}/app/control?appName=${appName}&command=${action}"
      if(slave != null && "" != slave) url = url + "&slaves=" + slave

    }

    logger.info("shell {}", url)
    val src = CatchUtil.getSrc(url, false)

    taskId = JSON.parseArray(src).getJSONObject(0).getJSONObject("task").getString("taskId")


    return taskId
  }


  def getTaskLog(taskId: String, slave: String): String = {
    val taskUrl = s"${masterUrl}/shell/process?taskId=${taskId}&slaves=${slave}"

    logger.info(" task log {}",taskUrl)
    CatchUtil.getSrc(taskUrl, false)
  }

  val dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  def listDir(appName: String, path: String, host: String):util.List[FileBean] = {

    //http://localhost:9003/app/list/log?appName=zookeeper
    val url = s"${masterUrl}/app/list/log?appName=${appName}&filePath=${path}"

    logger.info("url {}", url)

    val src = CatchUtil.getSrc(url, false)
    if(src != null && !src.isEmpty && src.startsWith("[")){

      logger.info("log list result {}", src)

      val files:util.List[FileBean] = JSON.parseArray(src).filter(_.asInstanceOf[JSONObject].getString("hostName") == host).last.asInstanceOf[JSONObject]
      .getJSONArray("files").map(l => {

        val obj = l.asInstanceOf[util.Map[String, Object]]

        val r = new FileBean()

        val d = new Date()
        val time = NumberUtil.getLongValue(obj.get("lastModifyTime"))
        d.setTime(time)

        r.setTimeString(dataFormat.format(d))

        val size = obj.get("size").asInstanceOf[Int]

        if(size >= 1024 * 1024 * 1024){
          r.setSizeString("%.2f".format(size * 1.0 / (1024 * 1024 * 1024)) + "GB")
        }else if(size >= 1024 * 1024){
          r.setSizeString("%.2f".format(size * 1.0 / (1024 * 1024) ) + "MB")
        }else if(size >= 1024){
          r.setSizeString("%.2f".format(size * 1.0 / 1024 ) + "KB")
        }else{
          r.setSizeString(size + "")
        }
        r.setIsDirectory(obj.get("isDirectory").asInstanceOf[Boolean])
        r.setName(obj.get("name").toString)

        r
      }).toList
      files
    }else{
      new util.ArrayList[FileBean]()
    }
  }


  def logDetail(appName: String, path: String, host: String, offset: Long, size: Int):Tuple2[Long, String] = {

    val url = s"${masterUrl}/app/log?appName=${appName}&filePath=${path}&slaves=${host}&offset=${offset}&size=${size}"
    logger.info("logDetail {}", url)
    val src = CatchUtil.getSrc(url, false)
    if(src != null && !src.isEmpty){
      val obj = JSON.parseArray(src).getJSONObject(0)
      (obj.getLong("offset"), obj.getString("msg"))
    }else{
      (0, "")
    }
  }

}
